<!--
* @author wn
* @date 2024/01/24 11:14:44
* @description: 将订单列表页 封装为组件
* v-for 会同时加载 多个 组价 这里 v-if 只加载选中的 card
!-->
<template>
	<!-- 订单列表 -->
	<scroll-view
		v-if="orderList.length"
		enable-back-to-top
		scroll-y
		refresher-enabled
		:refresher-triggered="isTriggered"
		@refresherrefresh="onRefresh"
		@scrolltolower="getMore"
	>
		<view class="card" v-for="item in orderList" :key="item.id">
			<!-- 订单信息 -->
			<view class="status">
				<text class="date">{{ item.createTime }}</text>
				<!-- 订单状态文字 -->
				<text>{{ orderStateList[item.orderState].text }}</text>
				<!-- 待评价/已完成/已取消 状态: 展示删除订单 -->
				<text
					:class="{ 'icon-delete': item.orderState >= 4 }"
					@tap="onOrderDelete(item.id)"
				></text>
			</view>
			<!-- 商品信息，点击商品跳转到订单详情，不是商品详情 -->
			<navigator
				v-for="sku in item.skus"
				:key="sku"
				class="goods"
				:url="`/pagesOrder/detail/detail?id=${item.id}`"
				hover-class="none"
			>
				<image mode="aspectFit" :src="sku.image" class="cover"></image>
				<view class="meta">
					<view class="name ellipsis">{{ sku.name }}</view>
					<text class="type">{{ sku.attrsText }}</text>
				</view>
			</navigator>
			<!-- 支付信息 -->
			<view class="payment">
				<text class="quantity">
					共{{ item.skus.reduce((oV, nV) => oV + nV.quantity, 0) }}件商品
				</text>
				<text>实付</text>
				<text class="amount symbol">{{ item.payMoney }}</text>
			</view>
			<!-- 订单操作按钮 -->
			<view class="action">
				<!-- 待付款状态：显示去支付按钮 -->
				<template v-if="item.orderState === OrderState.WaitForPay">
					<view class="button primary" @tap="onOrderPay(item.id)">去支付</view>
				</template>
				<template v-else>
					<navigator
						class="button secondary"
						:url="`/pagesOrder/create/create?orderId=${item.id}`"
						hover-class="none"
					>
						再次购买
					</navigator>
					<!-- 待收货状态: 展示确认收货 -->
					<view
						v-if="item.orderState === OrderState.WaitForReceived"
						class="button primary"
						@tap="onOrderConfirm(item.id)"
					>
						确认收货
					</view>
				</template>
			</view>
		</view>
		<!-- 底部提示文字 -->
		<view
			class="loading-text"
			:style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"
		>
			{{ isLoading ? '正在加载...' : '没有更多数据~' }}
		</view>
	</scroll-view>
	<card-list-skeleton v-else />
</template>
<script lang="ts" setup>
import { ref, watch, reactive } from 'vue'
import { getOrderListApi } from '@/api/order'
import { OrderState, orderStateList } from '@/types/orderState'
import {
	getOrderDetailApi,
	getOrderConsignmentApi,
	putOrderConfirmApi,
	deleteOrderApi,
	putOrderCancelApi,
	getOrderLogisticsApi,
} from '@/api/order'
import { getPayMockApi, getWxPayApi } from '@/api/pay'
import CardListSkeleton from './CardListSkeleton.vue'

// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()

// 订单状态
const { orderState } = defineProps<{ orderState: number }>()

// 请求参数
const queryParams = reactive<Required<OrderListParams>>({
	page: 1,
	pageSize: 5,
	orderState: orderState,
})

// 是否加载中  防止多次请求
const isLoading = ref(false)

// 观察 tabActive 计算出 订单列表
const orderList = ref<OrderItem[]>([])
const getOrderCard = async (params: Required<OrderListParams>) => {
	// 如果数据出于加载中，退出函数
	if (isLoading.value) return

	// 发送请求前，标记为加载中
	isLoading.value = true
	const { pages, items } = await getOrderListApi(params)
	// 数组追加 -- 初始不能为 undefined
	orderList.value?.push(...items)
	// 参数的页数 >= pages 已结束
	queryParams.page >= pages && (isFinish.value = true)
	// 发送请求后，重置标记
	isLoading.value = false
	// 如果是 下拉刷新 -- 关闭动画
	isTriggered.value && (isTriggered.value = false)
}

// 是否分页结束
const isFinish = ref(false)
// 是否触发下拉刷新
const isTriggered = ref(false)

// 下拉刷新--重置数据
const onRefresh = () => {
	// 开始动画
	isTriggered.value = true
	// 重置数据
	orderList.value = []
	isFinish.value = false
	if (queryParams.page === 1) {
		queryParams.page = 0
		queryParams.page = 1
	} else {
		queryParams.page = 1
	}
}

// 上拉加载更多
const getMore = () => {
	// 已经结束  不触发 watch
	if (isFinish.value)
		return uni.showToast({ icon: 'none', title: '没有更多数据~' })
	queryParams.page++
}
/**
 * watch queryParams
 */
watch(queryParams, async newV => getOrderCard(newV), { immediate: true })

// 订单支付
const onOrderPay = async (id: string) => {
	if (import.meta.env.DEV) {
		// 开发环境模拟支付
		await getPayMockApi({ orderId: id })
	} else {
		// #ifdef MP-WEIXIN

		// 正式环境支付：1.获取支付订单信息，2.调用微信支付API
		// const res = await getWxPayApi({ orderId: id })
		// await wx.requestPayment(res.result)

		// 注意：因小程序上线后被恶意投诉：理由为支付 0.01 元后不发货，现调整为模拟支付
		await getPayMockApi({ orderId: id })
		// #endif
	}
	// 成功提示
	uni.showToast({ title: '模拟支付成功' })
	// 模拟支付提示
	setTimeout(() => {
		wx.showModal({
			title: '温馨提示',
			content: '此交易是模拟支付，您并未付款，不会导致实际购买商品或服务',
			confirmText: '知道了',
			showCancel: false,
		})
	}, 2000)
	// 更新订单状态
	const order = orderList.value.find(v => v.id === id)
	order!.orderState = OrderState.WaitForDelivery
	// 支付成功，界面中删除订单
	removeOrderItemById(id)
}

// 确认收货
const onOrderConfirm = (id: string) => {
	uni.showModal({
		content: '为保障您的权益，请收到货并确认无误后，再确认收货',
		confirmColor: '#27BA9B',
		success: async res => {
			if (res.confirm) {
				await putOrderConfirmApi(id)
				uni.showToast({ icon: 'success', title: '确认收货成功' })
				// 确认成功，更新为待评价
				const order = orderList.value.find(v => v.id === id)
				order!.orderState = OrderState.WaitForEvaluate
				// 确认收货成功，界面中删除订单
				removeOrderItemById(id)
			}
		},
	})
}

// 删除订单
const onOrderDelete = (id: string) => {
	uni.showModal({
		content: '你确定要删除该订单？',
		confirmColor: '#27BA9B',
		success: async res => {
			if (res.confirm) {
				await deleteOrderApi({ ids: [id] })
				// 删除成功，界面中删除订单
				removeOrderItemById(id)
			}
		},
	})
}
// 剔除 指定的 订单
const removeOrderItemById = (id: string) => {
	const index = orderList.value.findIndex(v => v.id === id)
	orderList.value.splice(index, 1)
}
</script>
<style lang="scss">
// swiper
.symbol::before {
	content: '¥';
	font-size: 20rpx;
}
// 订单列表
.card {
	min-height: 100rpx;
	margin: 20rpx;
	padding: 20rpx;
	border-radius: 10rpx;
	background-color: #fff;
}

.status {
	display: flex;
	align-items: baseline;
	font-size: 28rpx;
	color: #999;
	margin-bottom: 15rpx;

	.date {
		color: #666;
		flex: 1;
	}
	.icon-delete {
		margin-left: 10rpx;
		line-height: 1;
		border-left: 1rpx solid #e3e3e3;
		padding-left: 10rpx;
	}
	.primary {
		color: #ff9240;
	}
}

.goods {
	display: flex;
	margin-bottom: 20rpx;
	.cover {
		width: 170rpx;
		height: 170rpx;
		margin-right: 20rpx;
		border-radius: 10rpx;
	}
	.meta {
		flex: 1;
		.name {
			height: 80rpx;
			font-size: 26rpx;
			color: #444;
			padding-top: 10rpx;
		}

		.type {
			display: inline-block;
			padding: 10rpx 15rpx;
			margin-top: 30rpx;
			font-size: 24rpx;
			border-radius: 4rpx;
			color: #888;
			background-color: #f7f7f8;
		}
	}
}

.payment {
	display: flex;
	justify-content: flex-end;
	align-items: baseline;
	padding: 20rpx 0;
	color: #999;
	font-size: 28rpx;
	border-bottom: 1rpx solid #eee;
	.quantity {
		font-size: 24rpx;
		margin-right: 16rpx;
	}
	.amount {
		color: #444;
		margin-left: 6rpx;
	}
}

.action {
	display: flex;
	justify-content: flex-end;
	padding-top: 20rpx;
	.button {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 180rpx;
		height: 60rpx;
		margin-left: 20rpx;
		border-radius: 60rpx;
		border: 1rpx solid #ccc;
		font-size: 26rpx;
		color: #444;
	}

	.primary {
		color: #fff;
		background-color: $primary-color;
	}
	.secondary {
		color: $primary-color;
		border-color: $primary-color;
	}
}

.loading-text {
	text-align: center;
	font-size: 28rpx;
	color: #666;
	padding-top: 20rpx;
}
</style>
